package com.apy.module.network

import android.content.Context
import androidx.annotation.WorkerThread
import com.apy.module.network.model.ApiResult
import com.apy.module.network.util.NetworkUtils
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import retrofit2.Response

/**
 * Main network manager class that handles all network operations
 */
class NetworkManager(
    private val context: Context,
    private val apiService: com.apy.module.network.api.ApiService
) {
    
    /**
     * Execute a GET request
     * @param apiCall The API call to execute
     * @return Flow of ApiResult with the response data
     */
    @WorkerThread
    suspend fun <T> get(
        apiCall: suspend () -> Response<T>
    ): Flow<ApiResult<T>> = flow {
        emit(ApiResult.Loading)
        
        val result = NetworkUtils.safeApiCall(context) {
            val response = apiCall()
            if (response.isSuccessful) {
                response.body() ?: throw Exception("Response body is null")
            } else {
                throw Exception("API Error: ${response.code()} - ${response.message()}")
            }
        }
        
        emit(result)
    }
    
    /**
     * Execute a POST request
     * @param apiCall The API call to execute
     * @return Flow of ApiResult with the response data
     */
    @WorkerThread
    suspend fun <T> post(
        apiCall: suspend () -> Response<T>
    ): Flow<ApiResult<T>> = flow {
        emit(ApiResult.Loading)
        
        val result = NetworkUtils.safeApiCall(context) {
            val response = apiCall()
            if (response.isSuccessful) {
                response.body() ?: throw Exception("Response body is null")
            } else {
                throw Exception("API Error: ${response.code()} - ${response.message()}")
            }
        }
        
        emit(result)
    }
    
    /**
     * Execute a PUT request
     * @param apiCall The API call to execute
     * @return Flow of ApiResult with the response data
     */
    @WorkerThread
    suspend fun <T> put(
        apiCall: suspend () -> Response<T>
    ): Flow<ApiResult<T>> = flow {
        emit(ApiResult.Loading)
        
        val result = NetworkUtils.safeApiCall(context) {
            val response = apiCall()
            if (response.isSuccessful) {
                response.body() ?: throw Exception("Response body is null")
            } else {
                throw Exception("API Error: ${response.code()} - ${response.message()}")
            }
        }
        
        emit(result)
    }
    
    /**
     * Execute a DELETE request
     * @param apiCall The API call to execute
     * @return Flow of ApiResult with the response data
     */
    @WorkerThread
    suspend fun <T> delete(
        apiCall: suspend () -> Response<T>
    ): Flow<ApiResult<T>> = flow {
        emit(ApiResult.Loading)
        
        val result = NetworkUtils.safeApiCall(context) {
            val response = apiCall()
            if (response.isSuccessful) {
                response.body() ?: throw Exception("Response body is null")
            } else {
                throw Exception("API Error: ${response.code()} - ${response.message()}")
            }
        }
        
        emit(result)
    }
}
